package conf

import (
	"os"

	"gitee.com/xinshortlink/internal/constants"
	"github.com/spf13/viper"
)

func NewViper() (*viper.Viper, error) {
	file := os.Getenv(constants.EnvConfFile)
	if file == "" {
		file = constants.XinConfFile
	}

	v := viper.New()
	v.SetConfigFile(file)
	return v, nil
}

type Conf struct {
	v        *viper.Viper
	Server   *ServerConf
	Logger   *LoggerConf
	Database *DataBaseConf
	Redis    *RedisConf
	Token    *TokenConf
	Short    *ShortConf
	Mq       *MqConf
}

func NewConf(v *viper.Viper) (*Conf, error) {
	conf := &Conf{v: v}

	v.SetDefault("server.port", 8080)
	v.SetDefault("redis.addr", "127.0.0.1:6379")
	v.SetDefault("redis.password", "123456")
	v.SetDefault("redis.db", 15)

	v.SetDefault("mq.rabbit.prefetchCount", 1)
	v.SetDefault("mq.rabbit.maxConcurrent", 100)

	if err := v.ReadInConfig(); err != nil {
		return nil, err
	}
	if err := v.UnmarshalExact(conf); err != nil {
		return nil, err
	}

	return conf, nil
}

type ServerConf struct {
	Port         int    // port
	Mode         string // debug test release
	AccessLog    bool   // 是否开启记录请求日志
	ReadTimeout  int    // 单位毫秒
	WriteTimeout int    // 单位毫秒
}

type DataBaseConf struct {
	Ip                    string // IP
	Port                  int    // 端口
	Username              string // 数据库用户名
	Password              string // 数据库密码
	DbName                string // 数据库名
	SlowSQLMillis         int    // 慢 SQL 时间阀值，单位毫秒。<0 禁止打印 SQL，=0 打印 SQL，>0 SQL 执行时间超过打印 SQL
	MaxOpenConns          int    // 数据库最大连接数,默认 50
	MaxIdleConns          int    // 数据库最大空闲连接数,默认 50
	ConnMaxLifetimeSecond int    // 连接存活秒时间. 默认 600 毫秒
}

type LoggerConf struct {
	Level      string            // 日志级别
	Files      []string          // 日志输出文件
	Fields     map[string]string // 日志追加字段
	Console    bool              // 是否开启控制台日志
	TimeLayout string            // 时间格式
	Rotatelogs bool              // 是否开启滚动日志
	MaxSize    int               // 日志文件最大 size，单位 MB
	MaxAge     int               // 旧日志保留最长时间
	MaxBackups int               // 保留旧日志文件个数
	Compress   bool              // 是否压缩旧日志
}

type TokenConf struct {
	SignKey string // 签名密钥
	Expire  int    // token 有效期；单位：秒
}

type RedisConf struct {
	Addr     string
	Password string
	DB       int
}

type ShortConf struct {
	Domain string // 短链接跳转域名
}

type MqConf struct {
	Name   string
	Rabbit *RabbitConf
}

type RabbitConf struct {
	Dsn           string
	ExchangeName  string
	RoutingKey    string
	QueueName     string
	PrefetchCount int // 预读取消息
	MaxConcurrent int // 消费消息最大并发量
}
